<template>
    <div class="qilin-QilinTable">
        <el-table
            ref="QilinTable"
            :data="ownTableConfig.tableData"
            :border="ownTableConfig?.elTableConfig?.border"
            :striper="ownTableConfig?.elTableConfig?.stripe || false"
            :size="ownTableConfig?.elTableConfig?.size || 'default'"
            :row-key="ownTableConfig?.elTableConfig?.rowKey || 'id'"
            :default-expand-all="ownTableConfig?.elTableConfig?.defaultExpandAll || false"
            :highlight-current-row="ownTableConfig?.elTableConfig?.highlightCurrentRow"
            :span-method="ownTableConfig?.elTableConfig?.spanMethod"
            height="100%"
            @select="selectRowData"
            @select-all="selectAllRowData"
            @selection-change="selectionChangeData"
            @row-click="rowClickData"
            @expand-change="expandChangeData"
            @current-change="currentChangeData"
        >
            <template
                v-for=" (item, index) in ownTableConfig.headerConfig "
                :key=" item.label+index || 'column-item-'+index "
            >
                <el-table-column
                    v-if="item.type === 'checkbox' && !item.isHide" type="selection"
                    :width="item.width ? item.width : ''"
                    :align="item.align || 'left'"
                ></el-table-column>
                <el-table-column
                    v-if="item.type === 'sortIndex' && !item.isHide"
                    :label="item.label || '序号'"
                    :align="item.align || 'left'"
                    :width="item.width ? item.width : '60px'"
                    v-bind="item"
                >
                    <template v-slot:default="scope">
                        <span>
                            {{ scope.$index + 1 }}
                        </span>
                    </template>
                </el-table-column>
                <!-- v-bind="item" 会影响表格树组件的收缩 -->
                <el-table-column
                    v-if="(!item.type || item.type === 'text') && !item.isHide"
                    :label="item.label"
                    :prop="item.prop"
                    :align="item.align || 'left'"
                    :width="item.width ? item.width : ''"
                    :min-width="item.minWidth ? item.minWidth : ''"
                    :show-overflow-tooltip="item.ellipsis || false"
                    :fixed="item.fixed ? item.fixed : false"
                >
                    <template v-slot:default="scope">
                        <span>{{ scope.row[item.prop] ?? (item.replaceValue || "-") }}</span>
                    </template>
                </el-table-column>
                <el-table-column
                    v-if="item.type === 'date' && !item.isHide"
                    :label="item.label"
                    :prop="item.prop"
                    :align="item.align || 'left'"
                    :width="item.width ? item.width : ''"
                    :min-width="item.minWidth ? item.minWidth : ''"
                    :show-overflow-tooltip="item.ellipsis || false"
                    v-bind="item"
                >
                    <template v-slot:default="scope">
                        <span>{{ getDate(scope.row[item.prop], item.format || "") }}</span>
                    </template>
                </el-table-column>
                <el-table-column
                    v-if="item.type === 'slot' && !item.isHide"
                    :label="item.label"
                    :prop="item.prop"
                    :align="item.align || 'left'"
                    :width="item.width ? item.width : ''"
                    :min-width="item.minWidth ? item.minWidth : ''"
                    :show-overflow-tooltip="item.ellipsis || false"
                    v-bind="item"
                >
                    <template v-slot:default="scope">
                        <div :class="['slot-box', item.class ? item.class : '']">
                            <slot :name="item.slotName" :data="{ scope, item }"></slot>
                        </div>
                    </template>
                </el-table-column>
                <el-table-column
                    v-if="item.type === 'operate' && !item.isHide"
                    :label="item.label"
                    :align="item.align || 'left'"
                    :width="item.widthFn ? item.widthFn(item) : item.width ? item.width : ''"
                    :min-width="item.minWidth ? item.minWidth : ''"
                    :fixed="item.fixed || 'right'"
                    v-bind="item"
                >
                    <template v-slot:default="scope">
                        <div
                            :class="[!item.hideSeparate ? 'operate-box' : '']"
                            style="text-align:center;"
                        >
                            <template
                                v-for="operateItem in item.operateOptions"
                                :key="operateItem.buttonName"
                            >
                                <el-button
                                    v-if="operateItem.isHide ? false :
                                        operateItem.isHideFn ? operateItem.isHideFn(scope.row, item, operateItem) : true "
                                    :type="operateItem.buttonType || 'default'"
                                    :size="operateItem.buttonSize || 'default'"
                                    :disabled="operateItem.disabled || (operateItem.isDisabled && operateItem.isDisabled(scope.row, item))"
                                    @click.stop="operateItem.buttonEvent && operateItem.buttonEvent(scope.row, item, scope, operateItem)"
                                    v-bind="operateItem"
                                >
                                    {{ operateItem.buttonName || "按钮" }}
                                </el-button>
                            </template>
                            <template v-if="item.moreOperateOptions && item.moreOperateOptions.length > 0">
                                <el-dropdown>
                                    <span class="el-dropdown-link">更多<el-icon class="el-icon--right"><arrow-down /></el-icon></span>
                                    <template #dropdown>
                                        <el-dropdown-item
                                            v-for="moreOperateItem in item.moreOperateOptions"
                                            :key="moreOperateItem.buttonName"
                                        >
                                            <el-button
                                                v-if="moreOperateItem.isHide ? false :
                                                    moreOperateItem.isHideFn ? moreOperateItem.isHideFn(scope.row, item, moreOperateItem) : true "
                                                :type="moreOperateItem.buttonType || 'default'"
                                                :size="moreOperateItem.buttonSize || 'default'"
                                                :disabled="moreOperateItem.disabled || (moreOperateItem.isDisabled && moreOperateItem.isDisabled(scope.row, item))"
                                                @click.stop="moreOperateItem.buttonEvent && moreOperateItem.buttonEvent(scope.row, item, scope, moreOperateItem)"
                                                v-bind="moreOperateItem"
                                            >
                                                {{ moreOperateItem.buttonName || "按钮" }}
                                            </el-button>
                                        </el-dropdown-item>
                                    </template>
                                </el-dropdown>
                            </template>
                        </div>
                    </template>
                </el-table-column>
                <el-table-column v-if="item.isShowExpandTooltip" type="expand" width="1">
                    <template v-slot:default="scope">
                        <span>
                            {{ item.expandTooltipFn && item.expandTooltipFn(scope.row, item) }}
                        </span>
                    </template>
                </el-table-column>
                <el-table-column
                    v-if="item.type === 'multiple' && !item.isHide"
                    :label="item.label"
                    :align="item.align || 'left'"
                >
                    <template
                        v-for=" (item1, index1) in item.children "
                        :key=" item1.label || 'column-item1-'+index1 "
                    >
                        <el-table-column
                            v-if="(!item1.type || item1.type === 'text') && !item1.isHide"
                            :label="item1.label"
                            :prop="item1.prop"
                            :align="item1.align || 'left'"
                            :width="item1.width ? item1.width : ''"
                            :min-width="item1.minWidth ? item1.minWidth : ''"
                            :show-overflow-tooltip="item1.ellipsis || false"
                        >
                            <template v-slot:default="scope">
                                <span>{{ scope.row[item1.prop] ?? (item1.replaceValue || "-") }}</span>
                            </template>
                        </el-table-column>
                        <el-table-column
                            v-if="item1.type === 'date' && !item1.isHide"
                            :label="item1.label"
                            :prop="item1.prop"
                            :align="item1.align || 'left'"
                            :width="item1.width ? item1.width : ''"
                            :min-width="item1.minWidth ? item1.minWidth : ''"
                            :show-overflow-tooltip="item1.ellipsis || false"
                            v-bind="item1"
                        >
                            <template v-slot:default="scope">
                                <span>{{ getDate(scope.row[item1.prop], item1.format || "") }}</span>
                            </template>
                        </el-table-column>
                        <el-table-column
                            v-if="item1.type === 'slot' && !item1.isHide"
                            :label="item1.label"
                            :prop="item1.prop"
                            :align="item1.align || 'left'"
                            :width="item1.width ? item1.width : ''"
                            :min-width="item1.minWidth ? item1.minWidth : ''"
                            :show-overflow-tooltip="item1.ellipsis || false"
                            v-bind="item1"
                        >
                            <template v-slot:default="scope">
                                <div class="slot-box">
                                    <slot :name="item1.slotName" :data="{ scope, item1 }"></slot>
                                </div>
                            </template>
                        </el-table-column>
                    </template>
                </el-table-column>
            </template>
            <template v-slot:empty>
                <div class="qilin-table-empty">
                    <img src="@/assets/images/dataEmpty.svg" alt="">
                    <p>暂无内容~</p>
                </div>
            </template>
        </el-table>
        <el-pagination
            v-if="!ownTableConfig.paginationsObj.isHide"
            :current-page="ownTableConfig.paginationsObj.currentPage"
            :page-sizes="ownTableConfig.paginationsObj.pageSizes"
            :page-size="ownTableConfig.paginationsObj.pageSize"
            :total="ownTableConfig.paginationsObj.total"
            :layout="ownTableConfig.paginationsObj.layout"
            @current-change="handleCurrentPage"
            @size-change="handleSizeChange"
            background
        ></el-pagination>
    </div>
</template>

<script setup>
import Qilin from "qilin-utils";

/*
    数据变量定义区域
*/
//获取当前表格元素DOM
const QilinTable = ref(null);
let currentRow = {};// 当前行数据
let curretnExpandRowId = null; //当前行数据id唯一标识


/*
    计算属性等代码区域
*/
// 接收来自父组件的传值
const propsValue = defineProps({
    tableConfig: {
        type: Object,
        default() {
            return {
                // el-table标签上的配置项
                elTableConfig: {
                    border: true, //是否带边框--默认true
                    stripe: false, //是否为斑马纹--默认false
                    size: "default", //表格大小--默认default
                    rowKey: "id",
                    highlightCurrentRow: false, //是否高亮当前行
                },
                // 表头相关配置项
                headerConfig: [
                    {
                        label: "姓名", //表头名称
                        type: "text", //表头的类型--默认为text
                        fixed: "right", //是否固定--当且仅当type为operate时生效--默认right
                        slotName: "", //slot元素的name，当且仅当type为slot时有效
                        format: "", //时间格式化配置
                        prop: "name", //对应后台数据名称
                        align: "left", //对齐方式--默认center
                        width: 60, //列宽-自适应宽度
                        minWidth: 60, //列宽-对应列的最小宽度
                        widthFn: "event", //空中列宽的方法-自适应宽度
                        ellipsis: false, //是否超出悬浮展示--默认false
                        replaceValue: "-", //若值为空，则默认显示为-
                        isHide: false, //是否隐藏某个表头，默认false
                        isShowExpandTooltip: false, //是否开启展开行功能
                        expandTooltipFn: "event", //展开行内容方法，内容由方法返回
                        hideSeparate: false, //操作按钮之间是否具有分隔符-默认false，没有
                        operateOptions: [ //操作栏按钮配置项--当且仅当type为operate生效
                            {
                                buttonName: "按钮", //按钮名称
                                buttonType: "default", //按钮类型--默认default
                                buttonSize: "small", //按钮大小--默认mini
                                buttonEvent: "event", //按钮点击事件
                                isHide: false, //是否隐藏该按钮
                                disable: false, //是否禁用
                                isDiabled: "event", //判断当前按钮是否禁用的方法
                                isHideFn: "event", //判断当前按钮是否隐藏的方法
                            }
                        ],
                        moreOperateOptions: [ //操作栏更多按钮配置项--当且仅当type为operate生效
                            {
                                buttonName: "按钮", //按钮名称
                                buttonType: "default", //按钮类型--默认default
                                buttonSize: "small", //按钮大小--默认mini
                                buttonEvent: "event", //按钮点击事件
                                isHide: false, //是否隐藏该按钮
                                disable: false, //是否禁用
                                isDiabled: "event", //判断当前按钮是否禁用的方法
                                isHideFn: "event", //判断当前按钮是否隐藏的方法
                            }
                        ]
                    }
                ],
                // 真实数据
                tableData: [],
                // 插槽名容器
                slotData: {},
                // 表格分页配置项
                paginationsObj: {
                    isHide: false, //是否隐藏分页器
                    currentPage: 1, //当前页
                    pageSize: 10, //当前每页数量
                    pageSizes: [10, 20, 30], //每页显示多少条选项集
                    total: 0, //表格总数量
                    layout: "total,sizes,prev,pager,next,jumper"
                }
            };
        }
    }
});

// 暴露父组件自定义方法
const emits = defineEmits(
    [
        "update:tableConfig",
        "changeCurrentPage",
        "changeCurrentSize",
        "selectRowData",
        "selectAllRowData",
        "selectionChangeData",
        "rowClickData",
        "expandChangeData",
        "currentChangeData"
    ]
);

// 组件自身的配置项
const ownTableConfig = computed({
    get() {
        return propsValue.tableConfig;
    },
    set(val) {
        emits("update:tableConfig", val);
    }
});

// 组件计算属性方法
const getDate = computed(() => {
    return function (date, format) {
        if (!date) {
            return "-";
        } else {
            return Qilin.Date.formatDate(date, format);
        };
    };
});


/*
    逻辑脚本代码区域
*/
// 监听表格行展开收缩事件监听
const expandChangeData = (row, expandedRows) => {
    // 正常以下这行代码不应写在这里，为方便统一修改，暂时如此写着......
    currentRow = row;
    curretnExpandRowId = row.id;
    if (expandedRows.length > 1) {
        QilinTable.value.toggleRowExpansion(expandedRows[0]);
    } else {
        if (expandedRows.length === 1) {
            curretnExpandRowId = expandedRows[0].id;
        } else {
            curretnExpandRowId = null;
        };
    };
    emits("expandChangeData", row, expandedRows, curretnExpandRowId);
};

// 监听切换页面事件
const handleCurrentPage = (page) => {
    emits("changeCurrentPage", page);
};
// 监听切换每页数量
const handleSizeChange = (size) => {
    emits("changeCurrentSize", size);
};
// 监听选择表格某行数据事件
const selectRowData = (selection, row) => {
    emits("selectRowData", selection, row);
};
// 监听选择表格全选数据事件
const selectAllRowData = (selection) => {
    emits("selectAllRowData", selection);
};
//监听选择表格事件
const selectionChangeData = (selection) => {
    emits("selectionChangeData", selection);
}
// 监听表格行单击事件
const rowClickData = (row, column, event) => {
    emits("rowClickData", row, column, event);
};
// 监听表格的当前行发生变化的事件--需配合属性highlight-current-row一起使用
const currentChangeData=(currentRow,oldCurrentRow)=>{
    emits("currentChangeData",currentRow,oldCurrentRow);
};

// 调用el-table的setCurrentRow事件监听--用于单选表格，设定某一行为选中行， 如果调用时不加参数，则会取消目前高亮行的选中状态。
const setCurrentRow = (row) => {
    QilinTable.value.setCurrentRow(row);
}
// 调用el-table的toggleRowExpansion事件监听--切换行的展开与收缩
const toggleRowExpansion = (row, flag) => {
    QilinTable.value.toggleRowExpansion(row, flag);
};
// 调用el-table的clearSelection事件监听--清空用户的选择
const clearSelection = () => {
    QilinTable.value.clearSelection();
};
// 调用el-table的toggleRowSelection事件监听--用于多选表格，切换某一行的选中状态
const toggleRowSelection=(row, selected)=>{
    QilinTable.value.toggleRowSelection(row, selected);
};


/*
    生命周期等代码区域
*/
// 暴露子组件的方法
defineExpose({
    toggleRowExpansion,
    clearSelection,
    toggleRowSelection,
    setCurrentRow
});

</script>

<style lang="scss" scoped>
.qilin-QilinTable {
    width: 100%;
    height: 100%;
    display: flex;
    flex-flow: column nowrap;
    flex: 1;
    overflow: hidden;
    >.el-table {
        flex: 1;
        .slot-box{
            height:100%;
            overflow:hidden;
            :deep(>span){
                display:inline-block;
                width:100%;
                // &.ellipsis{
                //     overflow:hidden;
                //     white-space:nowrap;
                //     text-overflow:ellipsis;
                // }
            }
        }
        .operate-box {
            >.el-button:not(:first-child) {
                position: relative;
                &::before {
                    position: absolute;
                    top: 50%;
                    left: -10%;
                    transform: translateY(-50%);
                    content: "";
                    width: 1px;
                    height: 60%;
                    background-color: $border-color;
                }
            }
            .el-dropdown {
                color: $primary-text-color;
                padding: 8px 18px;
                >span {
                    display: flex;
                    align-items: center;
                    outline: 0;
                    cursor: pointer;
                }
                &::before {
                    position: absolute;
                    top: 50%;
                    left: -10%;
                    transform: translateY(-50%);
                    content: "";
                    width: 1px;
                    height: 60%;
                    background-color: $border-color;
                    margin-left: 10px;
                }
            }
        }
        :deep(.el-table__empty-block){
            min-height:180px !important;
        }
        .qilin-table-empty {
            line-height: 24px;
        }
        :deep(.el-table__expand-column) {
            // border:none;
            border-right: 0 solid transparent;
            >div.cell {
                display: none;
            }
        }
        :deep(.el-table__expanded-cell) {
            background-color: rgba(0, 0, 0, 0.02);
            padding: 15px 50px;
        }
        .el-dropdown-link {
            color: #046ce7;
            padding: 9px 15px;
            width: 81px;
            display: flex;
            align-items: center;
            line-height: 16px;
            .el-icon--right {
                top: -2px;
                color: #046ce7;
            }
        }
    }
    >.el-pagination {
        justify-content: flex-end;
        float:right;
        padding:20px 0;
    }
}
</style>
